#version 120


//-----------Settings-----------
//-----------  设置  -----------

#define STRENGTH 0.5  //  模糊强度，建议设置为 0~2 之间的某个值。别的也许不会出现问题，但可能效果比较阴间（
#define FINENESS 5    //  模糊采样数（越大越卡，但越精细，建议 2~10 之间）

uniform sampler2D texture;
uniform sampler2D depthtex0;
uniform sampler2D gcolor;
uniform float frameTime;
uniform mat4 gbufferModelView;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferProjection;
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferPreviousModelView;
uniform mat4 gbufferPreviousProjection;
varying vec4 texcoord;
uniform vec3 cameraPosition;
uniform vec3 previousCameraPosition;
float saturate(float x){
    return clamp(x, 0.0, 1.0);
}
vec3 rand(vec2 coord){
    float noiseX = saturate(fract(sin(dot(coord, vec2(12.9898, 78.223))) * 43758.5453));
	float noiseY = saturate(fract(sin(dot(coord, vec2(12.9898, 78.223)*2.0)) * 43758.5453));
	float noiseZ = saturate(fract(sin(dot(coord, vec2(12.9898, 78.223)*3.0)) * 43758.5453));
	return vec3(noiseX, noiseY, noiseZ);
}
vec3 	GetTextureLod(in sampler2D tex, in vec2 coord, in int level) {
    return pow(texture2DLod(tex, coord, level).rgb, vec3(1.0f + 1.2f));
}
vec3 	GetColorTexture(in vec2 coord) {
    return GetTextureLod(gcolor, coord.st, 0).rgb;
}
vec3 MotionBlur(vec3 color) {
    float depth = texture2D(depthtex0, texcoord.st).x;
	vec4 currPosition = vec4(texcoord.x * 2.0f - 1.0f, texcoord.y * 2.0f - 1.0f, depth * 2.0f - 1.0f, 1.0f);
	vec4 fragposition = gbufferProjectionInverse * currPosition;
	fragposition = gbufferModelViewInverse * fragposition;
	fragposition /= fragposition.w;
	fragposition.xyz += cameraPosition;
	vec4 prePosition = fragposition;
	prePosition.xyz -= previousCameraPosition;
	prePosition = gbufferPreviousModelView * prePosition;
	prePosition = gbufferPreviousProjection * prePosition;
	prePosition /= prePosition.w;
	vec2 velocity = (currPosition - prePosition).st * 0.1f * (1.0 / frameTime) * 0.012;
	float maxVelocity = 0.05f;
	velocity = clamp(velocity, vec2(-maxVelocity), vec2(maxVelocity));
	if (depth < 0.7)	{
        		velocity *= 0.0;
	} else {
        velocity *= STRENGTH;
    }
    int samples = 0;
	float dither = rand(texcoord.st).x * 1.0;
	color.rgb = vec3(0.0f);
	for (int i = -FINENESS;i <= FINENESS;++i) {
    		vec2 coord = texcoord.st + velocity * (float(i + dither) / 2.0);
		if (coord.x > 0.0f && coord.x < 1.0f && coord.y > 0.0f && coord.y < 1.0f) {
            color += GetColorTexture(coord).rgb;
			samples += 1;
        }
    }
    color.rgb /= samples;
    return color;
}
/* DRAWBUFFERS: 0 */
void main() {
    vec3 color = vec3(0.0);
    color = MotionBlur(color);
	color = pow(color.rgb, vec3(1.0 / 2.2));
    gl_FragData[0] = vec4(color, 1.0);
}
